package org.jeecg.modules.scm.controller;

import cfca.trustsign.common.vo.request.tx3.Tx3ReqVO;
import cfca.trustsign.demo.op.CfcaOp;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import cpcn.dsp.demo.CpcnService;
import cpcn.dsp.demo.api.query.CompanyVerifyQuery;
import cpcn.dsp.demo.consts.DSPConsts;
import cpcn.dsp.demo.util.HttpsUtil;
import cpcn.dsp.institution.api.notice.NoticeRequest;
import cpcn.dsp.institution.api.notice.NoticeResponse;
import cpcn.dsp.institution.api.security.EncryptAndDecrypt;
import cpcn.dsp.institution.api.system.DSPInstitutionEnvironment;
import cpcn.dsp.institution.api.tx.personalinfo.Tx2324Request;
import cpcn.dsp.institution.api.tx.personalinfo.Tx2324Response;
import cpcn.dsp.institution.api.util.Base64;
import cpcn.dsp.institution.api.util.GUIDGenerator;
import cpcn.dsp.institution.api.util.QRCodeUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.flow.query.HistoryActivityQuery;
import org.jeecg.modules.flow.query.SubmitTaskQuery;
import org.jeecg.modules.scm.dto.ScmReceivablesTransferApplicationDto;
import org.jeecg.modules.scm.dto.TransferApplicationQueryPageDto;
import org.jeecg.modules.scm.entity.ScmCloudChain;
import org.jeecg.modules.scm.entity.ScmCusInfo;
import org.jeecg.modules.scm.entity.ScmReceivablesTransferApplication;
import org.jeecg.modules.scm.service.IScmCusInfoService;
import org.jeecg.modules.scm.service.IScmReceivablesTransferApplicationService;
import org.jeecg.modules.scm.service.IScmReceivablesTransferContractService;
import org.jeecg.modules.scm.vo.ScmReceivablesTransferApplicationVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import sun.misc.BASE64Encoder;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.*;

/**
 * @Description: scm_receivables_transfer_application
 * @Author: jeecg-boot
 * @Date: 2021-11-09
 * @Version: V1.0
 */
@Slf4j
@Api(tags = "应收账款转让申请")
@RestController
@RequestMapping("/transfer/scmReceivablesTransferApplication")
public class ScmReceivablesTransferApplicationController extends JeecgController<ScmReceivablesTransferApplication, IScmReceivablesTransferApplicationService> {

    public static String keystore_test = "./test.pfx";
    public static String publicKey_test = "./dsptest.cer";

    @Autowired
    private IScmReceivablesTransferApplicationService scmReceivablesTransferApplicationService;
    @Autowired
    private IScmReceivablesTransferContractService scmReceivablesTransferContractService;
    @Resource
    private ISysBaseAPI sysBaseAPI;
    @Autowired
    private IScmCusInfoService scmCusInfoService;

    private CpcnService cpcnService = new CpcnService();


    @ApiOperation("根据CFCA合同编号获取合同Base64编码后的字符串")
    @PostMapping(value = "/cfcaDownloadFile")
    public Result<?> testDownloadFile(@RequestBody JSONObject jsonObject) {
        String contractNo = jsonObject.getString("contractNo");
        byte[] byteContract = CfcaOp.downloadByteContract(contractNo);
        String base64Contract = org.apache.commons.codec.binary.Base64.encodeBase64String(byteContract);
        return Result.OK(base64Contract);
    }

    @PostMapping(value = "/testCfca")
    public Result<?> testCfca(@RequestBody JSONObject jsonObject) {
        try {
            String txCode = jsonObject.getString("txCode");
            String className = jsonObject.getString("className");
            JSONObject object = jsonObject.getJSONObject("Tx3ReqVO");
            Class c = Class.forName("cfca.trustsign.common.vo.request.tx3." + className);
            Tx3ReqVO cls = (Tx3ReqVO) JSON.parseObject(object.toJSONString(), c);
            String s = CfcaOp.send(txCode, cls);
            return Result.OK(JSONObject.parseObject(s));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            return Result.error("没有这个类");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("失败！");
        }
    }

    @PostMapping("/receiveNoticePage")
    public void receiveNoticePage(HttpServletRequest request, HttpServletResponse response) {
        log.info("前台回调");
        String message = request.getParameter("Message");
        String signature = request.getParameter("Signature");
        String dgtlenvlp = request.getParameter("Dgtlenvlp");
        String signSN = request.getParameter("SignSN");
        String encryptSN = request.getParameter("EncryptSN");
        //解析
        //1.初始化
        try {
            DSPInstitutionEnvironment.initialize(DSPConsts.Keystore_test, DSPConsts.myKeystorePassword_test, DSPConsts.publicKey_test, DSPConsts.MSG_ENCRYPT_20);
            NoticeRequest noticeRequest = new NoticeRequest(message, signature, dgtlenvlp, signSN, encryptSN);
            String plainText = noticeRequest.getPlainText();
            String txCode = noticeRequest.getTxCode();
            String code = noticeRequest.getCode();
            String noticeMessage = noticeRequest.getMessage();
            System.out.println(noticeMessage);
            log.info(noticeMessage);
            log.info(noticeRequest.toString());

            //////////////////////////////////
            //////解析明文后商户自己实现逻辑/////
            /////////////////////////////////
            //接收页面通知，响应的内容将会在识别结果页面展示
            PrintWriter out = response.getWriter();
            out.write(plainText);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @PostMapping("/receiveNoticeBackground")
    public void receiveNoticeBackground(HttpServletRequest request, HttpServletResponse response) {
        log.info("后台回调");
        String message = request.getParameter("Message");
        String signature = request.getParameter("Signature");
        String dgtlenvlp = request.getParameter("Dgtlenvlp");
        String signSN = request.getParameter("SignSN");
        String encryptSN = request.getParameter("EncryptSN");
        //解析
        //1.初始化
        try {
            DSPInstitutionEnvironment.initialize(DSPConsts.Keystore_test, DSPConsts.myKeystorePassword_test, DSPConsts.publicKey_test, DSPConsts.MSG_ENCRYPT_20);
            NoticeRequest noticeRequest = new NoticeRequest(message, signature, dgtlenvlp, signSN, encryptSN);
            String plainText = noticeRequest.getPlainText();
            String txCode = noticeRequest.getTxCode();
            String code = noticeRequest.getCode();
            String noticeMessage = noticeRequest.getMessage();
            System.out.println(plainText);
            log.info(noticeRequest.toString());
            ////////////////////////////////////////
            //////后台通知需要响应给数据服务SUCCESS/////
            ////////////////////////////////////////
            PrintWriter out = response.getWriter();
            BASE64Encoder encoder = new BASE64Encoder();
            String noticeResponse = NoticeResponse.getMessage();
            String data = encoder.encode(noticeResponse.getBytes("UTF-8"));
            out.write(data);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 2324-移动 H5 人脸识别随机数唇语
     *
     * @param
     * @return
     */
    @PostMapping(value = "/cpcn2324Test")
    @ApiOperation("2324-移动H5人脸识别随机数唇语")
    public Result<?> cpcn2324Test() throws Exception {
        //1.初始化
        DSPInstitutionEnvironment.initialize(keystore_test, DSPConsts.myKeystorePassword_test, publicKey_test, DSPConsts.MSG_ENCRYPT_20);
        //1.1 encryptSN、signSN值不为空，说明初始化证书成功
        System.out.println(DSPInstitutionEnvironment.encryptSN);
        System.out.println(DSPInstitutionEnvironment.signSN);
        //2.生成请求明文
        JSONObject json = new JSONObject();
        Tx2324Request tx2324Request = new Tx2324Request();
        tx2324Request.setInstitutionID("100827");// 机构号由中金分配
        tx2324Request.setTxSN(GUIDGenerator.genGUID());
        tx2324Request.setName("张三");
        tx2324Request.setIdentificationNumber("110101198001010037");
        tx2324Request.setFrontUrl("http://212.64.69.165:9999/jeecg-scm/transfer/scmReceivablesTransferApplication/receiveNoticePage");//需要更换为外网可以访问的ip
        tx2324Request.setFrontMethod("0");
        tx2324Request.setReturnImage("1");
        tx2324Request.setBackUrl("http://212.64.69.165:9999/jeecg-scm/transfer/scmReceivablesTransferApplication/receiveNoticeBackground");//需要更换为外网可以访问的ip
        tx2324Request.setThreshold("T5");//默认为T5
        tx2324Request.setRemark("0");//仅测试环境判断该字段1->不一致,2->未知，3->请求失败，其他->一致
        //报文处理
        tx2324Request.process();


        String plainText = tx2324Request.getRequestPlainText();
        System.out.println("请求明文：" + plainText);

        String reqMessage = tx2324Request.getRequestMessage();
        String reqSignature = tx2324Request.getRequestSignature();
        String requestDgtlEnvlp = tx2324Request.getRequestDgtlEnvlp();
        String requestSignSN = tx2324Request.getRequestSignSN();
        String requestEncryptSN = tx2324Request.getRequestEncryptSN();

        //生成参数
        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("message", reqMessage);
        paramMap.put("signature", reqSignature);
        paramMap.put("dgtlenvlp", requestDgtlEnvlp);
        paramMap.put("signSN", requestSignSN);
        paramMap.put("encryptSN", requestEncryptSN);
        //生成请求参数
        String requestString = EncryptAndDecrypt.createLinkStringByGet(paramMap);
        System.out.println("请求密文：" + requestString);
        //请求接口
        String result = HttpsUtil.post(DSPConsts.TX_URL_TEST, requestString, null);
        System.out.println("响应密文：" + result);

        String responsePlainText = null;
        String[] respMsg = result.split(",");
        if (respMsg.length == 1 && -1 == respMsg[0].indexOf(',')) {
            responsePlainText = Base64.decode(respMsg[0], "UTF-8");
        } else if (respMsg.length == 5) {
            String responseMessage = respMsg[0];
            String responseSignature = respMsg[1];
            String responseDgtlEnvlp = respMsg[2];
            String respSignSN = respMsg[3];
            String respEncryptSN = respMsg[4];

            Tx2324Response tx2324Response = new Tx2324Response(responseMessage, responseSignature, responseDgtlEnvlp, respSignSN, respEncryptSN);
            responsePlainText = tx2324Response.getResponsePlainText();
            if ("2000".equals(tx2324Response.getCode())) {
                //响应中的URL是活体链接地址
                String url = tx2324Response.getUrl();
                //提供二维码生成方法。建议二维码大小为500，机构方可自己根据页面来调试生成的二维码大小
                String qrCode = QRCodeUtil.createQRCode(url, 500, 500);
                //此方法为生成携带logo的二维码链接，logo图片存放在SRC的同级目录下。
                String qrCodeWithLogo = QRCodeUtil.createQRCodeWithLogo(url, "cpcnLogo_02.jpg", 500, 500);
            }
        }
        System.out.println("响应明文：" + responsePlainText);
        JSONObject jsonObject = JSONObject.parseObject(responsePlainText);
        return Result.OK(jsonObject);
    }

    /**
     * 企业工商四要素认证测试
     *
     * @param
     * @return
     */
    @PostMapping(value = "/cpcn1304Test")
    @ApiOperation("企业工商四要素认证测试")
    public Result<?> cpcn1304Test(CompanyVerifyQuery query) throws Exception {
        JSONObject jsonObject = cpcnService.companyVerify(query);
        return Result.OK(jsonObject);
    }

    /**
     * 进度查询
     *
     * @param query
     * @return
     */
    @AutoLog(value = "进度查询")
    @ApiOperation(value = "进度查询")
    @GetMapping(value = "/queryProgress")
    public Result<?> queryProgress(HistoryActivityQuery query) {
        Result<?> result = scmReceivablesTransferApplicationService.queryProgress(query);
        if (result.isSuccess()) {
            return result;
        } else {
            return Result.error("查询失败！");
        }
    }

    /**
     * 完成流程节点
     *
     * @param
     * @return
     */
    @AutoLog(value = "处理流程节点")
    @ApiOperation(value = "处理流程节点", notes = "处理流程节点")
    @PostMapping(value = "/handleTask")
    public Result<?> handleTask(@RequestBody SubmitTaskQuery query) {
        Result<?> result = scmReceivablesTransferApplicationService.handleTask(query);
        return result;
    }

    /**
     * 批量提交审批
     *
     * @param
     * @return
     */
    @AutoLog(value = "批量提交审批")
    @ApiOperation(value = "批量提交审批", notes = "批量提交审批")
    @PutMapping(value = "/approveBatch")
    public Result<List<List<Map<String, Object>>>> approveBatch(@RequestBody JSONObject jsonObject) {
        List<String> transferApplyIds = jsonObject.getJSONArray("transferApplyIds").toJavaList(String.class);
        Map<String, List<String>> map = scmReceivablesTransferApplicationService.approveBatch(transferApplyIds);
        List<String> successList = map.get("successList");
        List<String> noRightList = map.get("noRightList");
        List<String> notInApplicationList = map.get("notInApplicationList");
        Map<String, Object> successMap = new HashMap<>();
        Map<String, Object> noRightMap = new HashMap<>();
        Map<String, Object> notInApplicationMap = new HashMap<>();
        successMap.put("list", successList);
        successMap.put("msg", "提交审批成功");
        noRightMap.put("list", noRightList);
        noRightMap.put("msg", "无权提交审批");
        notInApplicationMap.put("list", notInApplicationList);
        notInApplicationMap.put("msg", "包含状态不是申请中");
        List<Map<String, Object>> success = new ArrayList<>();
        List<Map<String, Object>> fail = new ArrayList<>();
        success.add(successMap);
        fail.add(notInApplicationMap);
        fail.add(noRightMap);
        List<List<Map<String, Object>>> result = new ArrayList<>();
        result.add(success);
        result.add(fail);
        if (oConvertUtils.isEmpty(successList)) {
            return Result.error("批量提交审批失败！", result);
        } else if (successList.size() == transferApplyIds.size()) {
            return Result.OK("批量提交审批成功！", result);
        } else {
            return Result.OK("部分提交审批成功！", result);
        }
    }

    /**
     * 查询申请关联的云链单
     *
     * @param
     * @return
     */
    @AutoLog(value = "查询申请关联的云链单")
    @ApiOperation(value = "查询申请关联的云链单", notes = "查询申请关联的云链单，传入申请表ID")
    @PostMapping(value = "/findCloudChain")
    public Result<List<ScmCloudChain>> findCloudChain(@RequestParam(name = "id") String id) {
        List<ScmCloudChain> cloudChain = scmReceivablesTransferApplicationService.findCloudChain(id);
        if (oConvertUtils.isEmpty(cloudChain)) {
            return Result.error("没有关联云链单", null);
        }
        return Result.OK(cloudChain);
    }

    /**
     * 上传合同
     *
     * @param file
     * @return
     */
    @AutoLog(value = "上传贸易合同")
    @ApiOperation(value = "贸易合同上传", notes = "贸易合同上传")
    @PostMapping(value = "/uploadContract")
    public Result<?> uploadContract(@RequestParam(name = "file") MultipartFile file) {
        String path = scmReceivablesTransferApplicationService.uploadContract(file);
        return Result.OK(path);
    }


    /**
     * 分页列表查询
     *
     * @param transferApplicationQueryPageDto
     * @param pageNo
     * @param pageSize
     * @return
     */
    @AutoLog(value = "应收账款转让申请分页列表查询")
    @ApiOperation(value = "应收账款转让申请分页列表查询", notes = "应收账款转让申请分页列表查询")
    @GetMapping(value = "/queryPage")
    public Result<?> queryPage(TransferApplicationQueryPageDto transferApplicationQueryPageDto,
                               @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                               @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        Page<ScmReceivablesTransferApplication> page = new Page<ScmReceivablesTransferApplication>(pageNo, pageSize);
        IPage<ScmReceivablesTransferApplicationVo> voIPage = scmReceivablesTransferApplicationService.applicationList(transferApplicationQueryPageDto, page);
        return Result.OK(voIPage);
    }

    /**
     * 添加
     *
     * @param
     * @return
     */
    @AutoLog(value = "添加")
    @ApiOperation(value = "添加", notes = "添加")
    @PostMapping(value = "/add")
    public Result<?> add(@RequestBody ScmReceivablesTransferApplicationDto scmReceivablesTransferApplicationDto) {
        Result<?> result = new Result<>();

        //申请人企业身份认证
        ScmCusInfo cus = scmCusInfoService.getById(scmReceivablesTransferApplicationDto.getOwnerCusNo());
        CompanyVerifyQuery companyVerifyQuery = new CompanyVerifyQuery();
        companyVerifyQuery.setOrganizationName(cus.getCusName());
        companyVerifyQuery.setOrgIdentificationType("20");
        companyVerifyQuery.setOrgIdentificationNumber("150303195208070448");
        companyVerifyQuery.setName(cus.getLegalPerson());
        companyVerifyQuery.setIdentificationType("0");
        companyVerifyQuery.setIdentificationNumber("150303195208070448");
        companyVerifyQuery.setRemark("0");
        try {
            JSONObject companyVerifyResult = cpcnService.companyVerify(companyVerifyQuery);
            if (!"2000".equals(companyVerifyResult.getString("Code"))) {
                return Result.error("企业认证不通过！", companyVerifyResult);
            }
        } catch (Exception e) {
            return Result.error("企业认证出错");
        }


        if (oConvertUtils.listIsEmpty(scmReceivablesTransferApplicationDto.getCloudChianNos())) {
            return Result.error("请选择云链单！");
        }
        try {
            result = scmReceivablesTransferApplicationService.saveScmReceivablesTransferApplication(scmReceivablesTransferApplicationDto);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
        if (oConvertUtils.isEmpty(result.getResult())) {
            result.setMessage(result.getMessage() + "保存成功！");
        }
        return result;
    }

    /**
     * 编辑
     *
     * @param scmReceivablesTransferApplication
     * @return
     */
    @AutoLog(value = "编辑")
    @ApiOperation(value = "编辑", notes = "编辑")
    @PutMapping(value = "/edit")
    public Result<?> edit(@RequestBody ScmReceivablesTransferApplication scmReceivablesTransferApplication) {
        scmReceivablesTransferApplicationService.updateById(scmReceivablesTransferApplication);
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "通过id删除")
    @ApiOperation(value = "通过id删除", notes = "通过id删除")
    @DeleteMapping(value = "/delete")
    public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
        Integer delete = scmReceivablesTransferApplicationService.delete(id);
        if (delete > 0) {
            return Result.OK("删除成功!");
        } else {
            return Result.error("删除失败!");
        }
    }

    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @AutoLog(value = "批量删除")
    @ApiOperation(value = "批量删除", notes = "批量删除")
    @DeleteMapping(value = "/deleteBatch")
    public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
        this.scmReceivablesTransferApplicationService.deleteBatch(Arrays.asList(ids.split(",")));
        return Result.OK("批量删除成功!");
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @AutoLog(value = "通过id查询")
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @GetMapping(value = "/queryById")
    public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
        ScmReceivablesTransferApplication scmReceivablesTransferApplication = scmReceivablesTransferApplicationService.getById(id);
        if (scmReceivablesTransferApplication == null) {
            return Result.error("未找到对应数据");
        }
        return Result.OK(scmReceivablesTransferApplication);
    }

    /**
     * 导出excel
     *
     * @param request
     * @param scmReceivablesTransferApplication
     */
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(HttpServletRequest request, ScmReceivablesTransferApplication scmReceivablesTransferApplication) {
        return super.exportXls(request, scmReceivablesTransferApplication, ScmReceivablesTransferApplication.class, "scm_receivables_transfer_application");
    }

    /**
     * 通过excel导入数据
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
    public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
        return super.importExcel(request, response, ScmReceivablesTransferApplication.class);
    }

}
